#include "bsp_can.h"


static void can_gpio_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* 使能GPIO时钟*/
    RCC_AHB1PeriphClockCmd(CAN_TX_GPIO_CLK|CAN_RX_GPIO_CLK, ENABLE);

    /* 引脚源*/
    GPIO_PinAFConfig(CAN_TX_GPIO_PORT, CAN_RX_SOURCE, CAN_AF_PORT);
    GPIO_PinAFConfig(CAN_RX_GPIO_PORT, CAN_TX_SOURCE, CAN_AF_PORT);

    /* 配置 CAN TX 引脚 */
    GPIO_InitStructure.GPIO_Pin = CAN_TX_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_Init(CAN_TX_GPIO_PORT, &GPIO_InitStructure);

    /* 配置 CAN RX 引脚 */
    GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_Init(CAN_RX_GPIO_PORT, &GPIO_InitStructure);
}

static void can_mode_config(void)
{
    CAN_InitTypeDef        CAN_InitStructure;
    /************************CAN通信参数设置************************/
    /* Enable CAN clock */
    RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);

    /*CAN寄存器初始化*/
    CAN_DeInit(CAN1);
    CAN_StructInit(&CAN_InitStructure);

    /*CAN单元初始化*/
    CAN_InitStructure.CAN_TTCM=DISABLE;   //MCR-TTCM  关闭时间触发通信模式使能
    CAN_InitStructure.CAN_ABOM=DISABLE;         //MCR-ABOM  使能自动离线管理
    CAN_InitStructure.CAN_AWUM=DISABLE;         //MCR-AWUM  使用自动唤醒模式
    CAN_InitStructure.CAN_NART=DISABLE;        //MCR-NART  禁止报文自动重传
    CAN_InitStructure.CAN_RFLM=DISABLE;        //MCR-RFLM  接收FIFO 不锁定
                            // 溢出时新报文会覆盖原有报文
    CAN_InitStructure.CAN_TXFP=DISABLE; //MCR-TXFP发送FIFO优先级 取决于报文标识符
    // 可先配置为回环，回环通过后改为 正常模式
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;  //正常工作模式
    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 2个时间单元

    /* ss=1 bs1=4 bs2=2 位时间宽度为(1+4+2) 波特率即为时钟周期tq*(1+4+2)  */
    CAN_InitStructure.CAN_BS1=CAN_BS1_4tq; //BTR-TS1 时间段1 占用了4个时间单元
    CAN_InitStructure.CAN_BS2=CAN_BS2_2tq; //BTR-TS1 时间段2 占用了2个时间单元

    /* CAN Baudrate = 1 MBps (1MBps已为stm32的CAN最高速率) (CAN 时钟频率为 APB 1 = 42 MHz) */
    ////BTR-BRP 波特率分频器  定义了时间单元的时间长度 42/(1+4+2)/6=1 Mbps
    CAN_InitStructure.CAN_Prescaler = 6;
    CAN_Init(CANx, &CAN_InitStructure);
}

static void can_filter_config(void)
{
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;

	CAN_FilterInitStructure.CAN_FilterNumber = 0;		
	CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;		
	CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;	
	CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;					
	CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;					
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;				
	CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;				
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;		
	CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;				
	CAN_FilterInit(&CAN_FilterInitStructure);

}


static void can_nvic_config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Configure one bit for preemption priority */
    // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    /*中断设置*/
    NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;       //CAN RX中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    /*CAN通信中断使能*/
    CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE);
}

void bsp_can_init(void)
{
    can_gpio_init(); // GPIO初始化
    can_mode_config(); // CAN模式配置
    can_filter_config(); // CAN筛选器配置
    can_nvic_config(); // CAN中断配置
    
}


/*IDE位的标志*/
#define CAN_ID_STD             ((uint32_t)0x00000000)  /*标准ID */
#define CAN_ID_EXT             ((uint32_t)0x00000004)  /*扩展ID */

/*RTR位的标志*/
#define CAN_RTR_Data            ((uint32_t)0x00000000)  /*数据帧 */
#define CAN_RTR_Remote          ((uint32_t)0x00000002)  /*远程帧*/

/*
* 函数名：CAN_SetMsg
* 描述  ：CAN通信报文内容设置,设置一个数据内容为0-7的数据包
* 输入  ：无
* 输出  : 无
* 调用  ：外部调用
*/
void CAN_SetMsg(CanTxMsg *TxMessage)
{
    uint8_t ubCounter = 0;

    //TxMessage.StdId=0x00;
    TxMessage->ExtId=0x1314;                     //使用的扩展ID
    TxMessage->IDE=CAN_ID_EXT;                   //扩展模式
    TxMessage->RTR=CAN_RTR_DATA;                 //发送的是数据
    TxMessage->DLC=8;                            //数据长度为8字节

    /*设置要发送的数据0-7*/
    for (ubCounter = 0; ubCounter < 8; ubCounter++)
    {
        TxMessage->Data[ubCounter] = ubCounter;
    }
}



extern uint32_t flag ;      //用于标志是否接收到数据，在中断函数中赋值
extern CanRxMsg RxMessage;               //接收缓冲区
/********************************************************************/
void CAN1_RX0_IRQHandler(void)
{
    /*从邮箱中读出报文*/
    CAN_Receive(CANx, CAN_FIFO0, &RxMessage);

//    /* 比较ID是否为0x1314 */
//if ((RxMessage.ExtId==0x1314) && (RxMessage.IDE==CAN_ID_EXT) && (RxMessage.DLC==8) )
//    {
//        flag = 1;                       //接收成功
//    }
//    else
//    {
//        flag = 0;                      //接收失败
//    }
}

